<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
</head>

<body>
    <script>
        // 递归应用场景作业1：
        // 需求：用户角色为普通管理员，代码设计为没有配置roles代表不作权限控制，配置了roles代表指定权限的用户才能访问该页面
        // 目的：通过简单的需求案例熟悉权限路由的实现思路和算法，在面试时被问到可以更流畅地表述权限路由的实现思路
        // var role = 'normal'
        // // 原数组
        // var arr = [
        //     { path: '/', meta: { title: '首页' } },
        //     {
        //         path: '/super',
        //         meta: { title: '超级', roles: ['super'] },
        //         children: [
        //             {
        //                 path: '/super/list',
        //                 meta: { title: '超级列表' },
        //             },
        //         ],
        //     },
        //     { path: '/normal', meta: { title: '普通', roles: ['normal'] } },
        //     {
        //         path: '/other',
        //         meta: { title: '其它', roles: ['super', 'normal'] },
        //         children: [
        //             {
        //                 path: '/other/list',
        //                 meta: {
        //                     title: '其它列表',
        //                     roles: ['super', 'normal'],
        //                 },
        //             },
        //             {
        //                 path: '/other/add',
        //                 meta: {
        //                     title: '添加帐号',
        //                     roles: ['super'],
        //                 },
        //             },
        //         ],
        //     },
        // ]
        // // 期望的结果
        // var accessArr = [
        //     { path: '/', meta: { title: '首页' } },
        //     { path: '/normal', meta: { title: '普通', roles: ['normal'] } },
        //     {
        //         path: '/other',
        //         meta: { title: '其它', roles: ['super', 'normal'] },
        //         children: [
        //             {
        //                 path: '/other/list',
        //                 meta: {
        //                     title: '其它列表',
        //                     roles: ['super', 'normal'],
        //                 },
        //             },
        //         ],
        //     },
        // ]


        // 重复：对象里的children也是一个数组，和外面数组的结构是一样的，需要处理的逻辑也是一样的
        // 变化：就是根据对象里的children来计算，对象可能有children属性也可能没有
        // 出口：对象的children属性不存在就是递归的出口

        // 1.
        // // 配置了meta.roles，返回指定的布尔值
        // var res = arr.filter((item, index) => {
        //     if (item.meta && item.meta.roles) {
        //         // 如果包含用户的角色就返回true
        //         if (item.meta.roles.includes(role)) {
        //             // 再外层对象保留的前提下才需要判断children
        //             if (item.children) {
        //                 // 如果该对象有children
        //                 item.children = item.children.filter((v) => {
        //                     if (v.meta && v.meta.roles) {
        //                         // 如果包含用户的角色就返回true
        //                         if (v.meta.roles.includes(role)) {
        //                             // 再外层对象保留的前提下才需要判断children

        //                             return true
        //                         } else {
        //                             // 如果不包含返回false
        //                             return false
        //                         }
        //                     }
        //                     // 如果没有配置返回true
        //                     else {
        //                         return true
        //                     }
        //                 })

        //             }

        //             return true
        //         } else {
        //             // 如果不包含返回false
        //             return false
        //         }
        //     }
        //     // 如果没有配置返回true
        //     else {
        //         return true
        //     }
        // })
        // console.log(res);




        // 2.
        // function calc(rotes, role) {
        //     return rotes.filter((v) => {
        //         if (v.meta && v.meta.roles) {
        //             // 如果包含用户的角色就返回true
        //             if (v.meta.roles.includes(role)) {
        //                 // 再外层对象保留的前提下才需要判断children
        //                 if (v.children) {
        //                     v.children = calc(v.children, role)
        //                 }
        //                 return true
        //             } else {
        //                 // 如果不包含返回false
        //                 return false
        //             }
        //         }
        //         // 如果没有配置返回true
        //         else {
        //             return true
        //         }
        //     })
        // }
        // console.log(calc(arr, role));



        // 3.
        // function newArr(routes, role) {
        //     console.log(routes);
        //     var accessArr = [];
        //     routes.forEach(function (route) {
        //         console.log(route)
        //         if (!route.meta.roles || route.meta.roles.includes(role)) {
        //             var routes = { ...route };
        //             if (route.children) {
        //                 routes.children = newArr(route.children, role);
        //             }
        //             accessArr.push(routes);
        //         }
        //     });
        //     return accessArr;
        // }
        // var accessArr = newArr(arr, role);
        // console.log(accessArr);







        // 结论：所有的递归都可以用循环实现
        // 可以先用循环把功能找出来，然后再分析代码，找出重复、变化的部分及出口，逐步把重复代码抽离成一个函数、改变递归的调用=================================================================================================
        // // 递归作业2：使用循环递归的方式实现深拷贝
        // // 完全独立：深拷贝的对象与原始对象在内存中占据不同的地址空间
        // function myCopy(obj) {
        //     // 首先检查 obj 是否为 null 或者不是对象类型（包括数组）
        //     if (obj === null || typeof obj !== 'object') {
        //         //直接返回 obj，因为基本数据类型（如数字、字符串、布尔值）和 null 值不需要深拷贝
        //         return obj;
        //     }
        //     // 检查 obj 是否为 Date 对象的实例
        //     if (obj instanceof Date) {
        //         return new Date(obj);
        //     }
        //     // 检查 obj 是否为数组
        //     if (Array.isArray(obj)) {
        //         // 初始化一个空数组 copy 用于存放数组中每个元素的深拷贝。
        //         let copy = [];
        //         // 使用 for 循环遍历数组 obj 的每个元素
        //         for (let i = 0; i < obj.length; i++) {
        //             copy.push(myCopy(obj[i]));
        //         }
        //         // 完成数组元素的遍历和拷贝后，返回新的数组 copy
        //         return copy;
        //     }
        //     // 检查 obj 是否为对象类型
        //     if (typeof obj === 'object') {
        //         let copy = {};
        //         // 循环遍历对象 obj 的每个可枚举属性
        //         for (let key in obj) {
        //             // 使用 hasOwnProperty 方法检查属性 key 是否是对象 obj 的自有属性，以排除原型链上的属性
        //             if (obj.hasOwnProperty(key)) {
        //                 // 对于每个自有属性，递归调用 myCopy 函数进行深拷贝，并将结果赋值给 copy 对象的对应属性
        //                 copy[key] = myCopy(obj[key]);
        //             }
        //         }
        //         // 完成对象属性的遍历和拷贝后，返回新的 copy 对象
        //         return copy;
        //     }
        // }
        // var a = {
        //     name: 'kk',
        //     age: 18,
        //     sex: 'man'

        // }
        // var b = deepCopy(a)
        // console.log(b);

    </script>
</body>

</html>